package com.t.bricks.bussiness.controller.common;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import com.t.bricks.bussiness.service.common.CommonService;
import com.t.bricks.model.FileInfo;
import com.t.bricks.model.Logger;
import com.t.bricks.model.MsgEmity;
import com.t.bricks.model.OrderInfoList;
import com.t.bricks.model.Page;
import com.t.bricks.utils.function.app.HttpServletUtil;
import com.t.bricks.utils.function.date.TimeUtil;
import com.t.bricks.utils.function.json.JacksonShell;
import com.t.bricks.utils.function.reflect.ReflectUtil;
import com.t.bricks.utils.function.url.ResponseUtil;
import com.t.bricks.utils.modules.web.FindByPageParam;
import com.t.bricks.utils.spring.ModuleUtil;

/**
 * 控制层基类
 * 整合了常用的方法, 注意不允许添加RequestMapping方法,否则会直接开发到接口
 * @author huangxinbian
 * @param <S> 业务层定义
 * @param <E> 实体类定义
 * @param <C> 查询条件类
 */
public abstract class BaseController<S, E, C> {

	private static Logger logger = Logger.getLogger(BaseController.class);
	
	/**
	 * 控制操作,首位9不参与用6个数代表开关,0为不限制,1为限制
	 * 6个数的控制分别是:删除、修改、查询、导出、统计、步骤值可逆
	 * 其中前5个为'是否仅创建者可操作'后续为其它控制开关
	 */
	protected int onlyCreatorControl = 9000000;
	
	/**
	 * 是否已经初始化onlyCreatorControl变量,一旦初始化则值为null,否则为非null
	 * 原因:子类中设置此值时无法覆盖父类中的值,在父类方法中this.onlyCreatorControl得到的还是父类中定义的值
	 * 因此:必须通过其它方式将子类的属性覆盖父类
	 */
	private Integer isInitOnlyCreatorControl = 2;

	/**
	 * 业务层定义
	 */
	private Object classService = null;

	/**
	 * 实体类定义
	 */
	private Class<?> classEntity = null;

	/**
	 * 数据库表业务实现类
	 */
	private Class<?> classCondition = null;
	
	/**
	 * 
	 */
	private List<String> checkRepeatCombination = null;
	
	/**
	 * 检查待新增内容是否存在重复数据(单独字段重复即重复)集合
	 */
	private Map<String, Integer> checkRepeatAlone = null;
	
	/**
	 * 设置 检查待新增内容是否存在重复数据(多字段组合重复即重复)集合
	 * @return 返回的集合将覆盖父类的checkRepeatCombination成员,若返回null则不进行重复校验
	 */
	protected abstract List<String> setCheckRepeatCombination();
	
	/**
	 * 设置 检查待新增内容是否存在重复数据(单独字段重复即重复)集合
	 * @return 返回的集合将覆盖父类的checkRepeatAlone成员,若返回null则不进行重复校验
	 */
	protected abstract Map<String, Integer> setCheckRepeatAlone();
	
	/**
	 * 通用基本业务操作类
	 */
	@Autowired
	private CommonService commonService;

	/**
	 * 删除数据
	 * @param iVersion
	 * @param id 记录编号
	 * @return MsgEmity
	 */
	//[start]
	@ApiOperation(value="删除数据")
	@ApiImplicitParams({
		@ApiImplicitParam(name="iVersion", value="数据版本号", dataType="Integer", paramType="query", required=true),
		@ApiImplicitParam(name="id", value="记录编号", dataType="String", paramType="query", required=true)
	})
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="编号参数为空或不符合值"),
		@ApiResponse(code=8002, message="信息版本参数为空或不符合值"),
		@ApiResponse(code=7001, message="删除数据失败，系统中的数据可能已经被更新"),
		@ApiResponse(code=7002, message="删除数据失败，删除未能得到预期影响值"),
		@ApiResponse(code=7003, message="删除时发生异常"),
		@ApiResponse(code=7004, message="7004~7998、8003~8998为删除时发生的其它错误"),
		@ApiResponse(code=7999, message="删除成功")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/del")
	protected MsgEmity del(Integer iVersion, String id) {
		return this.delBase(iVersion, id);
	}

	/**
	 * 删除数据
	 * @param iVersion
	 * @param id 记录编号
	 * @return MsgEmity
	 */
	//[start]
	@ApiOperation(value="删除数据")
	@ApiImplicitParams({
		@ApiImplicitParam(name="iVersion", value="数据版本号", dataType="Integer", paramType="query", required=true),
		@ApiImplicitParam(name="id", value="记录编号", dataType="Integer", paramType="query", required=true)
	})
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="编号参数为空或不符合值"),
		@ApiResponse(code=8002, message="信息版本参数为空或不符合值"),
		@ApiResponse(code=7001, message="删除数据失败，系统中的数据可能已经被更新"),
		@ApiResponse(code=7002, message="删除数据失败，删除未能得到预期影响值"),
		@ApiResponse(code=7003, message="删除时发生异常"),
		@ApiResponse(code=7004, message="7004~7998、8003~8998为删除时发生的其它错误"),
		@ApiResponse(code=7999, message="删除成功")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/del")
	protected MsgEmity del(Integer iVersion, Integer id) {
		return this.delBase(iVersion, id);
	}

	/**
	 * 删除数据
	 * @param iVersion
	 * @param id 记录编号
	 * @return MsgEmity
	 */
	//[start]
	@ApiOperation(value="删除数据")
	@ApiImplicitParams({
		@ApiImplicitParam(name="iVersion", value="数据版本号", dataType="Integer", paramType="query", required=true),
		@ApiImplicitParam(name="id", value="记录编号", dataType="Long", paramType="query", required=true)
	})
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="编号参数为空或不符合值"),
		@ApiResponse(code=8002, message="信息版本参数为空或不符合值"),
		@ApiResponse(code=7001, message="删除数据失败，系统中的数据可能已经被更新"),
		@ApiResponse(code=7002, message="删除数据失败，删除未能得到预期影响值"),
		@ApiResponse(code=7003, message="删除时发生异常"),
		@ApiResponse(code=7004, message="7004~7998、8003~8998为删除时发生的其它错误"),
		@ApiResponse(code=7999, message="删除成功")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/del")
	protected MsgEmity del(Integer iVersion, Long id) {
		return this.delBase(iVersion, id);
	}

	/**
	 * 删除数据
	 * @param iVersion
	 * @param id 记录编号
	 * @return MsgEmity
	 */
	private MsgEmity delBase(Integer iVersion, Object id) {
		Object service = getService();

		boolean onlyCreator = isOnlyCreator(1);//分别是:删除、修改、查询、导出、统计
		
		if (null == service) {
			Class<?> entityClass = getEntityClass();
			return commonService.del(id, iVersion, onlyCreator, entityClass);
		}
		
		MsgEmity me = ReflectUtil.getMethod(service, "del", Integer.class, String.class, boolean.class);
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "del", Integer.class, Integer.class, boolean.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "del", Integer.class, Long.class, boolean.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "del", Integer.class, Object.class, boolean.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "del", Integer.class, String.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "del", Integer.class, Integer.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "del", Integer.class, Long.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "del", Integer.class, Object.class);
		}
		
		if (!me.isSuccess()) {
			Class<?> entityClass = getEntityClass();
			return commonService.del(id, iVersion, onlyCreator, entityClass);
		}

		try {
			Method method = me.getData();
			if (method.getParameterCount() == 3) {
				return (MsgEmity)method.invoke(service, iVersion, id, onlyCreator);
			}
			
			return (MsgEmity)method.invoke(service, iVersion, id);
		} catch (Exception e) {
			logger.error("执行del方法发生异常:", e.getMessage());
			return MsgEmity.err(5003, "执行del方法发生异常");
		}
	}

	/**
	 * 新增数据
	 * @param entity 数据库表实体对象
	 * @return MsgEmity
	 */
	//[start]
	@ApiOperation(value="新增数据")
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|Json数据对象}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8000, message="请求操作的参数为空"),
		@ApiResponse(code=8001, message="内部待转换的类型为空"),
		@ApiResponse(code=8002, message="服务端缺少json转换包的引用"),
		@ApiResponse(code=8003, message="服务端缺少json转换包的引用"),
		@ApiResponse(code=8004, message="待操作的数据不符合格式要求"),
		@ApiResponse(code=8011, message="检查数据时:待存储的数据实体不能为null"),
		@ApiResponse(code=8101, message="检查数据时:数据为null"),
		@ApiResponse(code=8102, message="检查数据时:数据某个值超出最大长度限制"),
		@ApiResponse(code=8103, message="检查数据时:数据某个值为空"),
		@ApiResponse(code=8021, message="验证数据是否重复时:待存储的数据实体不能为null"),
		@ApiResponse(code=8022, message="验证数据是否重复时:没有找到对应的dao实例,请检查代码规范"),
		@ApiResponse(code=8023, message="验证数据是否重复时:无法调用checkRepeatByAdd且发生了异常"),
		@ApiResponse(code=8024, message="验证数据是否重复时:检查数据是否重复失败"),
		@ApiResponse(code=8025, message="验证数据是否重复时:代码错误,checkRepeatByAdd方法返回的结构不是MsgEmity"),
		@ApiResponse(code=8026, message="验证数据是否重复时:数据重复"),
		@ApiResponse(code=8028, message="验证数据是否重复时:检查数据是否重复失败"),
		@ApiResponse(code=8311, message="补充数据时:待存储的数据实体不能为null"),
		@ApiResponse(code=8312, message="补充数据时:设置默认值失败"),
		@ApiResponse(code=7001, message="新增数据失败"),
		@ApiResponse(code=7002, message="新增时发生异常"),
		@ApiResponse(code=7003, message="7003~8998为新增时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/add")
	protected MsgEmity add(@RequestBody E entity) {
		Object service = getService();
		
		Class<?> entityClass = getEntityClass();

		if (null == checkRepeatCombination || null == checkRepeatAlone) {
			this.checkRepeatCombination = this.setCheckRepeatCombination();//设置 检查待新增内容是否存在重复数据(多字段组合重复即重复)集合
			this.checkRepeatAlone = this.setCheckRepeatAlone();//设置 检查待新增内容是否存在重复数据(单独字段重复即重复)集合
		}
		
		if (null == service) {
			return commonService.add(entity, entityClass, checkRepeatCombination, checkRepeatAlone);
		}

		List<String> checkList = ReflectUtil.getAttribute(service, "checkRepeatCombination");
		if (null != this.checkRepeatCombination && (null == checkList || checkList.size() < 1)) {
			ReflectUtil.changeAttribute(service, "checkRepeatCombination", this.checkRepeatCombination);
		}

		Map<String, Object> checkMap = ReflectUtil.getAttribute(service, "checkRepeatAlone");
		if (null != this.checkRepeatAlone && (null == checkMap || checkMap.size() < 1)) {
			ReflectUtil.changeAttribute(service, "checkRepeatAlone", this.checkRepeatAlone);
		}
		
		MsgEmity me = ReflectUtil.getMethod(service, "add", entityClass);
		if (!me.isSuccess()) {
			Class<?> baseClass = ReflectUtil.findBaseClass(entityClass);
			me = ReflectUtil.getMethod(service, "add", baseClass);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "add", Object.class);
		}

		if (!me.isSuccess()) {
			return commonService.add(entity, entityClass, checkRepeatCombination, checkRepeatAlone);
		}

		try {
			Method method = me.getData();
			return (MsgEmity)method.invoke(service, entity);
		} catch (Exception e) {
			logger.error("执行add方法发生异常:", e.getMessage());
			return MsgEmity.err(5003, "执行add方法发生异常");
		}
	}

	/**
	 * 修改数据
	 * @param entity 数据库表实体对象
	 * @return MsgEmity
	 */
	//[start]
	@ApiOperation(value="修改数据")//, response=E.class)
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|Json数据对象}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8000, message="请求操作的参数为空"),
		@ApiResponse(code=8001, message="内部待转换的类型为空"),
		@ApiResponse(code=8002, message="服务端缺少json转换包的引用"),
		@ApiResponse(code=8003, message="服务端缺少json转换包的引用"),
		@ApiResponse(code=8004, message="待操作的数据不符合格式要求"),
		@ApiResponse(code=8011, message="检查数据时:待存储的数据实体不能为null"),
		@ApiResponse(code=8012, message="检查数据时:待存储的数据实体信息版本号为空"),
		@ApiResponse(code=8013, message="检查数据时:待存储的数据实体信息版本号小于1"),
		@ApiResponse(code=8014, message="检查数据时:待存储的数据实体定义不能为null"),
		@ApiResponse(code=8015, message="检查数据时:待存储的数据实体定义中缺乏'isKey'的DataInfo注解"),
		@ApiResponse(code=8016, message="检查数据时:信息编号不能为空"),
		@ApiResponse(code=8101, message="检查数据时:数据为null"),
		@ApiResponse(code=8102, message="检查数据时:数据某个值超出最大长度限制"),
		@ApiResponse(code=8103, message="检查数据时:数据某个值为空"),
		@ApiResponse(code=8021, message="验证数据是否重复时:待存储的数据实体不能为null"),
		@ApiResponse(code=8022, message="验证数据是否重复时:没有找到对应的dao实例,请检查代码规范"),
		@ApiResponse(code=8023, message="验证数据是否重复时:无法调用checkRepeatByEdit且发生了异常"),
		@ApiResponse(code=8024, message="验证数据是否重复时:检查数据是否重复失败"),
		@ApiResponse(code=8025, message="验证数据是否重复时:代码错误,checkRepeatByEdit方法返回的结构不是MsgEmity"),
		@ApiResponse(code=8026, message="验证数据是否重复时:数据重复"),
		@ApiResponse(code=8028, message="验证数据是否重复时:检查数据是否重复失败"),
		@ApiResponse(code=8311, message="补充数据时:待存储的数据实体不能为null"),
		@ApiResponse(code=7001, message="修改数据失败，数据可能已经被删除"),
		@ApiResponse(code=7002, message="修改数据失败，系统中的数据可能已经被更新"),
		@ApiResponse(code=7003, message="修改数据失败，未能得到预期影响值(1)"),
		@ApiResponse(code=7004, message="修改数据失败，修改操作发生异常"),
		@ApiResponse(code=7005, message="7005~8998为修改时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/edit")
	protected MsgEmity edit(@RequestBody E entity) {
		Object service = getService();
		
		Class<?> entityClass = getEntityClass();

		boolean onlyCreator = isOnlyCreator(2);//分别是:删除、修改、查询、导出、统计

		if (null == checkRepeatCombination || null == checkRepeatAlone) {
			this.checkRepeatCombination = this.setCheckRepeatCombination();//设置 检查待新增内容是否存在重复数据(多字段组合重复即重复)集合
			this.checkRepeatAlone = this.setCheckRepeatAlone();//设置 检查待新增内容是否存在重复数据(单独字段重复即重复)集合
		}
		
		if (null == service) {
			return commonService.edit(entity, entityClass, onlyCreator, this.checkRepeatCombination, this.checkRepeatAlone);
		}

		List<String> checkList = ReflectUtil.getAttribute(service, "checkRepeatCombination");
		if (null != this.checkRepeatCombination && (null == checkList || checkList.size() < 1)) {
			ReflectUtil.changeAttribute(service, "checkRepeatCombination", this.checkRepeatCombination);
		}

		Map<String, Integer> checkMap = ReflectUtil.getAttribute(service, "checkRepeatAlone");
		if (null != this.checkRepeatAlone && (null == checkMap || checkMap.size() < 1)) {
			ReflectUtil.changeAttribute(service, "checkRepeatAlone", this.checkRepeatAlone);
		}

		MsgEmity me = ReflectUtil.getMethod(service, "edit", entityClass, boolean.class);
		if (!me.isSuccess()) {
			Class<?> baseClass = ReflectUtil.findBaseClass(entityClass);
			me = ReflectUtil.getMethod(service, "edit", baseClass, boolean.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "edit", Object.class, boolean.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "edit", entityClass);
		}
		
		if (!me.isSuccess()) {
			Class<?> baseClass = ReflectUtil.findBaseClass(entityClass);
			me = ReflectUtil.getMethod(service, "edit", baseClass);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "edit", Object.class);
		}

		if (!me.isSuccess()) {
			return commonService.edit(entity, entityClass, onlyCreator, checkRepeatCombination, checkRepeatAlone);
		}

		try {
			Method method = me.getData();
			if (method.getParameterCount() == 2) {
				return (MsgEmity)method.invoke(service, entity, onlyCreator);
			}
			
			return (MsgEmity)method.invoke(service, entity);
		} catch (Exception e) {
			logger.error("执行edit方法发生异常:", e.getMessage());
			return MsgEmity.err(5003, "执行edit方法发生异常");
		}
	}

	/**
	 * 根据记录编号取对象
	 * @param id 记录编号
	 * @return MsgEmity
	 */
	//[start]
	@ApiOperation(value="根据记录编号取对象")//, response=E.class)
	@ApiImplicitParams({
		@ApiImplicitParam(name="id", value="记录编号", dataType="String", paramType="query", required=true)
	})
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|Json数据对象}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="编号参数能为空"),
		@ApiResponse(code=7001, message="数据不存在"),
		@ApiResponse(code=7002, message="查询发生异常"),
		@ApiResponse(code=7003, message="7003~8998为修改时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/find/id")
	protected MsgEmity findById(String id) {
		return this.findByIdBase(id);
	}

	/**
	 * 根据记录编号取对象
	 * @param id 记录编号
	 * @return MsgEmity
	 */
	//[start]
	@ApiOperation(value="根据记录编号取对象")//, response=E.class)
	@ApiImplicitParams({
		@ApiImplicitParam(name="id", value="记录编号", dataType="Integer", paramType="query", required=true)
	})
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|Json数据对象}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="编号参数能为空"),
		@ApiResponse(code=7001, message="数据不存在"),
		@ApiResponse(code=7002, message="查询发生异常"),
		@ApiResponse(code=7003, message="7003~8998为修改时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/find/id")
	protected MsgEmity findById(Integer id) {
		return this.findByIdBase(id);
	}

	/**
	 * 根据记录编号取对象
	 * @param id 记录编号
	 * @return MsgEmity
	 */
	//[start]
	@ApiOperation(value="根据记录编号取对象")//, response=E.class)
	@ApiImplicitParams({
		@ApiImplicitParam(name="id", value="记录编号", dataType="Long", paramType="query", required=true)
	})
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|Json数据对象}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="编号参数能为空"),
		@ApiResponse(code=7001, message="数据不存在"),
		@ApiResponse(code=7002, message="查询发生异常"),
		@ApiResponse(code=7003, message="7003~8998为修改时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/find/id")
	protected MsgEmity findById(Long id) {
		return this.findByIdBase(id);
	}

	/**
	 * 根据记录编号取对象
	 * @param id 记录编号
	 * @return MsgEmity
	 */
	protected MsgEmity findByIdBase(Object id) {
		Object service = getService();
		
		if (null == service) {
			Class<?> entityClass = getEntityClass();
			return commonService.findById(id, entityClass);
		}

		MsgEmity me = ReflectUtil.getMethod(service, "findById", String.class);
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "findById", Integer.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "findById", Long.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "findById", Object.class);
		}

		if (!me.isSuccess()) {
			Class<?> entityClass = getEntityClass();
			return commonService.findById(id, entityClass);
		}

		try {
			Method method = me.getData();
			return (MsgEmity)method.invoke(service, id);
		} catch (Exception e) {
			logger.error("执行findById方法发生异常:", e.getMessage());
			return MsgEmity.err(5003, "执行findById方法发生异常");
		}
	}

	/**
	 * 根据关键值取对象集合
	 * @param entity 数据库表实体对象
	 * @return MsgEmity
	 */
	//[start]
	@ApiOperation(value="根据关键值取对象集合")//, response=E.class)
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|Json数据对象集合}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8000, message="条件参数不能为空"),
		@ApiResponse(code=8001, message="内部待转换的类型为空"),
		@ApiResponse(code=8002, message="服务端缺少json转换包的引用"),
		@ApiResponse(code=8003, message="服务端缺少json转换包的引用"),
		@ApiResponse(code=8004, message="待操作的数据不符合格式要求"),
		@ApiResponse(code=7001, message="数据不存在"),
		@ApiResponse(code=7002, message="查询发生异常"),
		@ApiResponse(code=7003, message="7003~8998为修改时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/find/key")
	protected MsgEmity findByKey(@RequestBody E entity) {
		Object service = getService();

		Class<?> entityClass = getEntityClass();
		
		if (null == service) {
			return commonService.findByKey(entity, entityClass);
		}
		
		MsgEmity me = ReflectUtil.getMethod(service, "findByKey", entityClass);
		if (!me.isSuccess()) {
			Class<?> baseClass = ReflectUtil.findBaseClass(entityClass);
			me = ReflectUtil.getMethod(service, "findByKey", baseClass);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "findByKey", Object.class);
		}
		
		if (!me.isSuccess()) {
			return commonService.findByKey(entity, entityClass);
		}

		try {
			Method method = me.getData();
			return (MsgEmity)method.invoke(service, entity);
		} catch (Exception e) {
			logger.error("执行findByKey方法发生异常:", e.getMessage());
			return MsgEmity.err(5003, "执行findByKey方法发生异常");
		}
	}

	/**
	 * 根据记录编号查询符合分页数据的某条记录
	 * @param id 记录编号
	 * @return MsgEmity
	 */
	//[start]
	@ApiOperation(value="根据记录编号查询符合分页数据的某条记录")//, response=E.class)
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|Json数据对象}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="编号参数能为空"),
		@ApiResponse(code=7001, message="数据不存在"),
		@ApiResponse(code=7002, message="查询发生异常"),
		@ApiResponse(code=7003, message="7003~8998为修改时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/find/page/row")
	protected MsgEmity findByPageRow(String id) {
		return this.findByPageRowBase(id);
	}

	/**
	 * 根据记录编号查询符合分页数据的某条记录
	 * @param id 记录编号
	 * @return MsgEmity
	 */
	//[start]
	@ApiOperation(value="根据记录编号查询符合分页数据的某条记录")//, response=E.class)
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|Json数据对象}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="编号参数能为空"),
		@ApiResponse(code=7001, message="数据不存在"),
		@ApiResponse(code=7002, message="查询发生异常"),
		@ApiResponse(code=7003, message="7003~8998为修改时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/find/page/row")
	protected MsgEmity findByPageRow(Integer id) {
		return this.findByPageRowBase(id);
	}

	/**
	 * 根据记录编号查询符合分页数据的某条记录
	 * @param id 记录编号
	 * @return MsgEmity
	 */
	//[start]
	@ApiOperation(value="根据记录编号查询符合分页数据的某条记录")//, response=E.class)
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|Json数据对象}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="编号参数能为空"),
		@ApiResponse(code=7001, message="数据不存在"),
		@ApiResponse(code=7002, message="查询发生异常"),
		@ApiResponse(code=7003, message="7003~8998为修改时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/find/page/row")
	protected MsgEmity findByPageRow(Long id) {
		return this.findByPageRowBase(id);
	}

	/**
	 * 根据记录编号查询符合分页数据的某条记录
	 * @param id 记录编号
	 * @return MsgEmity
	 */
	//[start]
	@ApiOperation(value="根据记录编号查询符合分页数据的某条记录")//, response=E.class)
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|Json数据对象}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="编号参数能为空"),
		@ApiResponse(code=7001, message="数据不存在"),
		@ApiResponse(code=7002, message="查询发生异常"),
		@ApiResponse(code=7003, message="7003~8998为修改时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/find/page/row")
	private MsgEmity findByPageRowBase(Object id) {
		Object service = getService();

		boolean onlyCreator = isOnlyCreator(3);//分别是:删除、修改、查询、导出、统计
		
		if (null == service) {
			Class<?> entityClass = getEntityClass();
			return commonService.findByPageRow(id, onlyCreator, entityClass);
		}
		
		MsgEmity me = ReflectUtil.getMethod(service, "findByPageRow", String.class, boolean.class);
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "findByPageRow", Integer.class, boolean.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "findByPageRow", Long.class, boolean.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "findByPageRow", Object.class, boolean.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "findByPageRow", String.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "findByPageRow", Integer.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "findByPageRow", Long.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "findByPageRow", Object.class);
		}

		if (!me.isSuccess()) {
			Class<?> entityClass = getEntityClass();
			return commonService.findByPageRow(id, onlyCreator, entityClass);
		}

		try {
			Method method = me.getData();
			if (method.getParameterCount() == 2) {
				return (MsgEmity)method.invoke(service, id, onlyCreator);
			}
			
			return (MsgEmity)method.invoke(service, id);
		} catch (Exception e) {
			logger.error("执行findByPageRow方法发生异常:", e.getMessage());
			return MsgEmity.err(5003, "执行findByPageRow方法发生异常");
		}
	}

	/**
	 * 查询分页数据
	 * @param findByPageParam 分页查询条件组合类
	 * 结构参考: {"page": 分页请求信息对象, "orders": 排序信息对象集合, "sLikeStr": 全文检索, "condition": 查询条件对象}
	 * @return MsgEmity 返回查询结果
	 */
	//[start]
	@ApiOperation(value="查询分页数据")//, response=E.class)
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|Json数据对象集合}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=7001, message="查询数量失败且发生异常"),
		@ApiResponse(code=7002, message="查询数据发生异常，值为null"),
		@ApiResponse(code=7003, message="查询分页数据发生异常"),
		@ApiResponse(code=7004, message="7004~8998为修改时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/find/page")
	protected MsgEmity findByPage(@RequestBody FindByPageParam<C> findByPageParam) {
		Object service = getService();

		boolean onlyCreator = isOnlyCreator(3);//分别是:删除、修改、查询、导出、统计
		
		if (null == service) {
			Class<?> entityClass = getEntityClass();
			return commonService.findByPage(
				findByPageParam.getPage(),
				findByPageParam.getOrders(),
				findByPageParam.getsLikeStr(),
				findByPageParam.getCondition(),
				onlyCreator,
				entityClass
			);
		}
		
		Class<?> conditionClass = getConditionClass();//获取查询条件类的类定义
		
		MsgEmity me = ReflectUtil.getMethod(service, "findByPage", Page.class,
				OrderInfoList.class, String.class, conditionClass, boolean.class);
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "findByPage", Page.class,
					OrderInfoList.class, String.class, conditionClass);
		}
		
		if (!me.isSuccess()) {
			Class<?> entityClass = getEntityClass();
			return commonService.findByPage(
				findByPageParam.getPage(),
				findByPageParam.getOrders(),
				findByPageParam.getsLikeStr(),
				findByPageParam.getCondition(),
				onlyCreator,
				entityClass
			);
		}

		try {
			Method method = me.getData();
			if (method.getParameterCount() == 5) {
				return (MsgEmity)method.invoke(service, findByPageParam.getPage(),
						findByPageParam.getOrders(),
						findByPageParam.getsLikeStr(),
						findByPageParam.getCondition(),
						onlyCreator);
			}
			
			return (MsgEmity)method.invoke(service, findByPageParam.getPage(),
					findByPageParam.getOrders(),
					findByPageParam.getsLikeStr(),
					findByPageParam.getCondition());
		} catch (Exception e) {
			logger.error("执行findByPage方法发生异常:", e.getMessage());
			return MsgEmity.err(5003, "执行findByPage方法发生异常");
		}
	}

	/**
	 * 查询指定时间内数据
	 * @param sDateSt
	 * @param sDateEd
	 * @return MsgEmity 返回查询结果
	 */
	//[start]
	@ApiOperation(value="查询指定时间内数据")//, response=E.class)
	@ApiImplicitParams({
		@ApiImplicitParam(name="sDateSt", value="开始时间", dataType="String", paramType="query", required=true),
		@ApiImplicitParam(name="sDateEd", value="结束时间", dataType="String", paramType="query", required=true)
	})
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|Json数据对象集合}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=7001, message="查询数量失败且发生异常"),
		@ApiResponse(code=7002, message="查询数据发生异常，值为null"),
		@ApiResponse(code=7003, message="查询分页数据发生异常"),
		@ApiResponse(code=7004, message="7004~8998为修改时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/find/date")
	protected MsgEmity findByDate(String sDateSt, String sDateEd) {
		Object service = getService();

		boolean onlyCreator = isOnlyCreator(5);//分别是:删除、修改、查询、导出、统计
		
		if (null == service) {
			Class<?> entityClass = getEntityClass();
			return commonService.findByDate(sDateSt, sDateEd, onlyCreator, entityClass);
		}
		
		Object oDateSt = sDateSt;
		Object oDateEd = sDateEd;
		
		MsgEmity me = ReflectUtil.getMethod(service, "findByDate", String.class,
				String.class, boolean.class);
		if (!me.isSuccess()) {
			oDateSt = TimeUtil.toDate(sDateSt);
			oDateEd = TimeUtil.toDate(sDateEd);
			me = ReflectUtil.getMethod(service, "findByDate", Date.class,
					Date.class, boolean.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "findByDate", String.class, String.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "findByDate", Date.class, Date.class);
			oDateSt = TimeUtil.toDate(sDateSt);
			oDateEd = TimeUtil.toDate(sDateEd);
		}
		
		if (!me.isSuccess()) {
			Class<?> entityClass = getEntityClass();
			return commonService.findByDate(sDateSt, sDateEd, onlyCreator, entityClass);
		}

		try {
			Method method = me.getData();
			if (method.getParameterCount() == 3) {
				return (MsgEmity)method.invoke(service, oDateSt, oDateEd, onlyCreator);
			}
			
			return (MsgEmity)method.invoke(service, oDateSt, oDateEd);
		} catch (Exception e) {
			logger.error("执行findByDate方法发生异常:", e.getMessage());
			return MsgEmity.err(5003, "执行findByDate方法发生异常");
		}
	}
	
	/**
	 * 创建Excel文件
	 * @param findByPageParam 分页查询条件组合类,注意:分页信息将被抛弃
	 * 结构参考:  {"page": 分页请求信息对象(被抛弃), "orders": 排序信息对象集合, "sLikeStr": 全文检索, "condition": 查询条件对象}
	 * @return MsgEmity 返回结构中data为创建的经过压缩的Excel内容,接收端需要进行解压,msg为文件名
	 */
	//[start]
	@ApiOperation(value="创建Excel文件", notes="返回Excel文件")
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 异常码}|文件下载"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=6001, message="没有指定模板"),
		@ApiResponse(code=6002, message="没有指定保存位置"),
		@ApiResponse(code=6003, message="保存路径错误"),
		@ApiResponse(code=6004, message="没有数据可导出"),
		@ApiResponse(code=6005, message="读取模板文件失败"),
		@ApiResponse(code=6006, message="保存文件时失败"),
		@ApiResponse(code=6100, message="待压缩字符串为空(文件内容为空)"),
		@ApiResponse(code=6101, message="压缩时发生异常"),
		@ApiResponse(code=7001, message="查询数据发生异常,执行的返回值为:null,预期值不应为null"),
		@ApiResponse(code=7002, message="查询导出文件用的数据发生异常"),
		@ApiResponse(code=7003, message="7003~8998为修改时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/export")
	protected ResponseEntity<byte[]> export(@RequestBody FindByPageParam<C> findByPageParam) {
		HttpServletRequest request = ModuleUtil.currentRequest();
		HttpServletResponse response = ModuleUtil.currentResponse();
		
		return this.export(request, response, findByPageParam);
	}
	
	/**
	 * 创建Excel文件
	 * @param findByPageParam 分页查询条件组合类,注意:分页信息将被抛弃
	 * 结构参考:  {"page": 分页请求信息对象(被抛弃), "orders": 排序信息对象集合, "sLikeStr": 全文检索, "condition": 查询条件对象}
	 * @return MsgEmity 返回结构中data为创建的经过压缩的Excel内容,接收端需要进行解压,msg为文件名
	 */
	//[start]
	@ApiOperation(value="创建Excel文件", notes="返回Excel文件")
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 异常码}|文件下载"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=6001, message="没有指定模板"),
		@ApiResponse(code=6002, message="没有指定保存位置"),
		@ApiResponse(code=6003, message="保存路径错误"),
		@ApiResponse(code=6004, message="没有数据可导出"),
		@ApiResponse(code=6005, message="读取模板文件失败"),
		@ApiResponse(code=6006, message="保存文件时失败"),
		@ApiResponse(code=6100, message="待压缩字符串为空(文件内容为空)"),
		@ApiResponse(code=6101, message="压缩时发生异常"),
		@ApiResponse(code=7001, message="查询数据发生异常,执行的返回值为:null,预期值不应为null"),
		@ApiResponse(code=7002, message="查询导出文件用的数据发生异常"),
		@ApiResponse(code=7003, message="7003~8998为修改时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/export")
	protected ResponseEntity<byte[]> export(HttpServletRequest request, HttpServletResponse response,
			@RequestBody FindByPageParam<C> findByPageParam) {
		Object service = getService();

		boolean onlyCreator = isOnlyCreator(4);//分别是:删除、修改、查询、导出、统计
		
		if (null == service) {
			Class<?> entityClass = getEntityClass();
			MsgEmity me = commonService.export(findByPageParam.getOrders(),
					findByPageParam.getsLikeStr(),
					findByPageParam.getCondition(),
					onlyCreator,
					entityClass);
			
			if (!me.isSuccess()) {
				ResponseUtil.setResponseMsg(response, JacksonShell.toJSONString(me));//将消息数据写入response
				return null;
			}
			
			return HttpServletUtil.downloadToByte(request, me.getMsg(), ((String)me.getData()).getBytes());
		}
		
		Class<?> conditionClass = getConditionClass();//获取查询条件类的类定义

		MsgEmity me = ReflectUtil.getMethod(service, "export",
				OrderInfoList.class, String.class, conditionClass, boolean.class);
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "export",
					OrderInfoList.class, String.class, conditionClass);
		}
		
		if (!me.isSuccess()) {
			Class<?> entityClass = getEntityClass();
			me = commonService.export(findByPageParam.getOrders(),
					findByPageParam.getsLikeStr(),
					findByPageParam.getCondition(),
					onlyCreator,
					entityClass);
			
			if (!me.isSuccess()) {
				ResponseUtil.setResponseMsg(response, JacksonShell.toJSONString(me));//将消息数据写入response
				return null;
			}
			
			return HttpServletUtil.downloadToByte(request, me.getMsg(), ((String)me.getData()).getBytes());
		}

		try {
			Method method = me.getData();
			if (method.getParameterCount() == 4) {
				me = (MsgEmity)method.invoke(service,
						findByPageParam.getOrders(),
						findByPageParam.getsLikeStr(),
						findByPageParam.getCondition(),
						onlyCreator);
			}
			
			me = (MsgEmity)method.invoke(service,
					findByPageParam.getOrders(),
					findByPageParam.getsLikeStr(),
					findByPageParam.getCondition());
		} catch (Exception e) {
			logger.error("执行export方法发生异常:", e.getMessage());
			ResponseUtil.setResponseMsg(response, JacksonShell.toJSONString(me));//将消息数据写入response
			return null;
		}
		
		if (!me.isSuccess()) {
			ResponseUtil.setResponseMsg(response, JacksonShell.toJSONString(me));//将消息数据写入response
			return null;
		}
		
		return HttpServletUtil.downloadToByte(request, me.getMsg(), ((String)me.getData()).getBytes());
	}

	/**
	 * 修改状态
	 * @param id 编号
	 * @param iState 状态值
	 * @param iVersion 记录版本号
	 * @param sMemo 备注
	 * @return MsgEmity 返回执行情况
	 */
	//[start]
	@ApiOperation(value="修改状态", notes="状态值不可逆修改")
	@ApiImplicitParams({
		@ApiImplicitParam(name="sMemo", value="备注", dataType="String", paramType="query", required=false),
		@ApiImplicitParam(name="iVersion", value="数据版本号", dataType="Integer", paramType="query", required=true),
		@ApiImplicitParam(name="iState", value="状态值", dataType="Integer", paramType="query", required=true),
		@ApiImplicitParam(name="id", value="记录编号", dataType="String", paramType="query", required=true)
	})
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": Excel内容}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="编号为空"),
		@ApiResponse(code=8002, message="状态值为空"),
		@ApiResponse(code=8003, message="版本号小于1"),
		@ApiResponse(code=7001, message="没有找到对应数据"),
		@ApiResponse(code=7002, message="更新状态失败，系统中的数据可能已经被更新"),
		@ApiResponse(code=7003, message="更新状态失败，状态禁止逆操作"),
		@ApiResponse(code=7004, message="更新状态未能得到预期影响值(预期1)"),
		@ApiResponse(code=7005, message="更新状态时发生异常"),
		@ApiResponse(code=7006, message="7006~8998为修改时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/change/state")
	protected MsgEmity changeState(String id, Integer iState, Integer iVersion, String sMemo) {
		return changeStateBase(id, iState, iVersion, sMemo);
	}

	/**
	 * 修改状态
	 * @param id 编号
	 * @param iState 状态值
	 * @param iVersion 记录版本号
	 * @param sMemo 备注
	 * @return MsgEmity 返回执行情况
	 */
	//[start]
	@ApiOperation(value="修改状态", notes="状态值不可逆修改")
	@ApiImplicitParams({
		@ApiImplicitParam(name="sMemo", value="备注", dataType="String", paramType="query", required=false),
		@ApiImplicitParam(name="iVersion", value="数据版本号", dataType="Integer", paramType="query", required=true),
		@ApiImplicitParam(name="iState", value="状态值", dataType="Integer", paramType="query", required=true),
		@ApiImplicitParam(name="id", value="记录编号", dataType="Integer", paramType="query", required=true)
	})
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": Excel内容}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="编号为空"),
		@ApiResponse(code=8002, message="状态值为空"),
		@ApiResponse(code=8003, message="版本号小于1"),
		@ApiResponse(code=7001, message="没有找到对应数据"),
		@ApiResponse(code=7002, message="更新状态失败，系统中的数据可能已经被更新"),
		@ApiResponse(code=7003, message="更新状态失败，状态禁止逆操作"),
		@ApiResponse(code=7004, message="更新状态未能得到预期影响值(预期1)"),
		@ApiResponse(code=7005, message="更新状态时发生异常"),
		@ApiResponse(code=7006, message="7006~8998为修改时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/change/state")
	protected MsgEmity changeState(Integer id, Integer iState, Integer iVersion, String sMemo) {
		return changeStateBase(id, iState, iVersion, sMemo);
	}

	/**
	 * 修改状态
	 * @param id 编号
	 * @param iState 状态值
	 * @param iVersion 记录版本号
	 * @param sMemo 备注
	 * @return MsgEmity 返回执行情况
	 */
	//[start]
	@ApiOperation(value="修改状态", notes="状态值不可逆修改")
	@ApiImplicitParams({
		@ApiImplicitParam(name="sMemo", value="备注", dataType="String", paramType="query", required=false),
		@ApiImplicitParam(name="iVersion", value="数据版本号", dataType="Integer", paramType="query", required=true),
		@ApiImplicitParam(name="iState", value="状态值", dataType="Integer", paramType="query", required=true),
		@ApiImplicitParam(name="id", value="记录编号", dataType="Long", paramType="query", required=true)
	})
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": Excel内容}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="编号为空"),
		@ApiResponse(code=8002, message="状态值为空"),
		@ApiResponse(code=8003, message="版本号小于1"),
		@ApiResponse(code=7001, message="没有找到对应数据"),
		@ApiResponse(code=7002, message="更新状态失败，系统中的数据可能已经被更新"),
		@ApiResponse(code=7003, message="更新状态失败，状态禁止逆操作"),
		@ApiResponse(code=7004, message="更新状态未能得到预期影响值(预期1)"),
		@ApiResponse(code=7005, message="更新状态时发生异常"),
		@ApiResponse(code=7006, message="7006~8998为修改时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/change/state")
	protected MsgEmity changeState(Long id, Integer iState, Integer iVersion, String sMemo) {
		return changeStateBase(id, iState, iVersion, sMemo);
	}

	/**
	 * 修改状态
	 * @param id 编号
	 * @param iState 状态值
	 * @param iVersion 记录版本号
	 * @param sMemo 备注
	 * @return MsgEmity 返回执行情况
	 */
	private MsgEmity changeStateBase(Object id, Integer iState, Integer iVersion, String sMemo) {
		Object service = getService();
		
		Class<?> entityClass = getEntityClass();
		
		if (null == service) {
			return commonService.changeState(id, iState, iVersion, sMemo, entityClass);
		}

		MsgEmity me = ReflectUtil.getMethod(service, "changeState",
				String.class, Integer.class, Integer.class, String.class);
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "changeState",
					String.class, Integer.class, Integer.class, String.class);
		}

		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "changeState",
					Integer.class, Integer.class, Integer.class, String.class);
		}

		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "changeState",
					Long.class, Integer.class, Integer.class, String.class);
		}
		
		if (!me.isSuccess()) {
			me = ReflectUtil.getMethod(service, "changeState",
					Object.class, Integer.class, Integer.class, String.class);
		}

		if (!me.isSuccess()) {
			return commonService.changeState(id, iState, iVersion, sMemo, entityClass);
		}

		try {
			Method method = me.getData();
			return (MsgEmity)method.invoke(service, id, iState, iVersion, sMemo);
		} catch (Exception e) {
			logger.error("执行changeState方法发生异常:", e.getMessage());
			return MsgEmity.err(5003, "执行changeState方法发生异常");
		}
	}
	
	/**
	 * 查询树形结构数据
	 * @return MsgEmity
	 */
	//[start]
	@ApiOperation(value="查询树形结构数据")
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|Json数据对象集合}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="获取树形数据信息为空"),
		@ApiResponse(code=8101, message="没有数据无法进行树结构创建"),
		@ApiResponse(code=8102, message="对象字段中的编号属性名称必须提供"),
		@ApiResponse(code=8103, message="对象字段中的上级编号属性名称必须提供"),
		@ApiResponse(code=8104, message="对象字段中的子节点集合属性名称必须提供")
	})
	//[end]
	protected MsgEmity findByTree() {
		Object service = getService();
		
		Class<?> entityClass = getEntityClass();
		
		if (null == service) {
			return commonService.findByTree(entityClass);
		}

		MsgEmity me = ReflectUtil.getMethod(service, "findByTree");
		if (!me.isSuccess()) {
			return commonService.findByTree(entityClass);
		}

		try {
			Method method = me.getData();
			return (MsgEmity)method.invoke(service);
		} catch (Exception e) {
			logger.error("执行findByTree方法发生异常:", e.getMessage());
			return MsgEmity.err(5003, "执行findByTree方法发生异常");
		}
	}
	
	/**
	 * 清理指定用户的缓存
	 * @param sUser 用户编号
	 * @return
	 */
	//[start]
	@ApiOperation(value="清理指定用户的缓存", notes="若不提供用户编号则删除所有用户的缓存")
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="没有启用缓存"),
		@ApiResponse(code=8002, message="试图删除所有用户的缓存失败"),
		@ApiResponse(code=8003, message="试图删除指定用户的缓存失败"),
		@ApiResponse(code=8999, message="删除成功")
	})
	//[end]
	protected MsgEmity clearCache(String sUser) {
		Object service = getService();
		
		Class<?> entityClass = getEntityClass();
		
		if (null == service) {
			return commonService.clearCache(sUser, entityClass);
		}

		MsgEmity me = ReflectUtil.getMethod(service, "clearCache", String.class);
		if (!me.isSuccess()) {
			return commonService.clearCache(sUser, entityClass);
		}

		try {
			Method method = me.getData();
			return (MsgEmity)method.invoke(service, sUser);
		} catch (Exception e) {
			logger.error("执行clearCache方法发生异常:", e.getMessage());
			return MsgEmity.err(5003, "执行clearCache方法发生异常");
		}
	}

	/**
	 * 查询组结构数据
	 * @param sGroupName
	 * @return
	 */
	//[start]
	@ApiOperation(value="查询组结构数据")
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|Json数据对象集合}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="获取组结构数据信息为空"),
		@ApiResponse(code=8101, message="没有数据无法进行组结构创建"),
		@ApiResponse(code=8102, message="对象字段中的编号属性名称必须提供"),
		@ApiResponse(code=8103, message="对象字段中的上级编号属性名称必须提供"),
		@ApiResponse(code=8104, message="对象字段中的子节点集合属性名称必须提供")
	})
	//[end]
	protected MsgEmity findByGroup(String sGroupName) {
		Object service = getService();
		
		Class<?> entityClass = getEntityClass();
		
		if (null == service) {
			return commonService.findByGroup(sGroupName, entityClass);
		}

		MsgEmity me = ReflectUtil.getMethod(service, "findByGroup", String.class);
		if (!me.isSuccess()) {
			return commonService.findByGroup(sGroupName, entityClass);
		}

		try {
			Method method = me.getData();
			return (MsgEmity)method.invoke(service, sGroupName);
		} catch (Exception e) {
			logger.error("执行findByGroup方法发生异常:", e.getMessage());
			return MsgEmity.err(5003, "执行findByGroup方法发生异常");
		}
	}

	/**
	 * 文件上传
	 * @param file 文件
	 * @param sPath 存储路径(不含文件名的相对路径)
	 * @param sFileName 存储的文件名
	 * @param iCover 是否覆盖(1:是;2:否)
	 * @return
	 */
	//[start]
	@ApiOperation(value="文件上传", notes="将文件上传到指定相对目录下")
	@ApiImplicitParams({
		@ApiImplicitParam(name="file", value="文件", dataType="__file", paramType="form", required=true),
		@ApiImplicitParam(name="sPath", value="存储路径(不含文件名的相对路径)", dataType="String", paramType="query", required=true),
		@ApiImplicitParam(name="sFileName", value="存储的文件名", dataType="String", paramType="query", required=false),
		@ApiImplicitParam(name="iCover", value="是否覆盖(1:是;2:否)", dataType="String", paramType="query", required=false)
	})
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|保存相对地址}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="请求存储的路径为空"),
		@ApiResponse(code=8002, message="出于安全考虑,请求存储的路径不能是绝对路径"),
		@ApiResponse(code=8003, message="指定的文件名不合法"),
		@ApiResponse(code=8004, message="存在同名文件,放弃保存"),
		@ApiResponse(code=8005, message="文件保存发生异常"),
		@ApiResponse(code=8006, message="文件保存失败")
	})
	//[end]
	//@RequestMapping(method=RequestMethod.POST, value="/file/up")
	protected MsgEmity upFile(@RequestParam("file") MultipartFile file,
			String sPath, String sFileName, Integer iCover) {
		return commonService.upFile(file, sPath, sFileName, iCover, fileType());
	}

	/**
	 * 判断文件是否存在
	 * @param sPath 存储路径(含文件名的相对路径)
	 * @return
	 */
	//[start]
	@ApiOperation(value="判断文件是否存在", notes="判断相对路径下的文件是否存在")
	@ApiImplicitParams({
		@ApiImplicitParam(name="sPath", value="存储路径(含文件名的相对路径)", dataType="String", paramType="query", required=true)
	})
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|文件记录编号}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="未找到文件"),
		@ApiResponse(code=8999, message="文件存在")
	})
	//[end]
	//@RequestMapping(method=RequestMethod.POST, value="/file/check")
	protected MsgEmity checkFile(String sPath) {
		return commonService.checkFile(sPath, fileType());
	}

	/**
	 * 读取文件内容
	 * @param sPath 存储路径(含文件名的相对路径)
	 * @return
	 */
	//[start]
	@ApiOperation(value="读取文件内容", notes="读取相对路径下的文件内容")
	@ApiImplicitParams({
		@ApiImplicitParam(name="sPath", value="存储路径(含文件名的相对路径)", dataType="String", paramType="query", required=true)
	})
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|文件内容}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="未找到文件"),
		@ApiResponse(code=8002, message="读取文件失败")
	})
	//[end]
	//@RequestMapping(method=RequestMethod.POST, value="/file/read")
	protected MsgEmity readFile(String sPath) {
		return commonService.readFile(sPath, fileType());
	}

	/**
	 * 删除文件
	 * @param sPath 存储路径(含文件名的相对路径)
	 * @return
	 */
	//[start]
	@ApiOperation(value="删除文件", notes="删除相对路径下的文件")
	@ApiImplicitParams({
		@ApiImplicitParam(name="sPath", value="存储路径(含文件名的相对路径)", dataType="String", paramType="query", required=true)
	})
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="删除失败,请检查文件是否在占用中")
	})
	//[end]
	//@RequestMapping(method=RequestMethod.POST, value="/file/del")
	protected MsgEmity delFile(String sPath) {
		return commonService.delFile(sPath, fileType());
	}

	/**
	 * 下载文件
	 * @param sPath 存储路径(含文件名的相对路径)
	 * @param request
	 * @param response
	 */
	//[start]
	@ApiOperation(value="下载文件", notes="下载相对路径下的文件内容")
	@ApiImplicitParams({
		@ApiImplicitParam(name="sPath", value="存储路径(含文件名的相对路径)", dataType="String", paramType="query", required=true)
	})
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|文件}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="未找到文件")
	})
	//[end]
	//@RequestMapping(method=RequestMethod.GET, value="/file/down")
	protected void download(String sPath,
			HttpServletRequest request, HttpServletResponse response) {
		commonService.download(request, response, sPath, fileType());
	}

	/**
	 * 获取文件(消费者使用)
	 * @param sPath 存储路径(含文件名的相对路径)
	 * @return MsgEmity 返回结构中data为创建的经过压缩的Excel内容,接收端需要进行解压,msg为文件名
	 */
	//[start]
	@ApiOperation(value="获取文件", notes="下载相对路径下的文件内容")
	@ApiImplicitParams({
		@ApiImplicitParam(name="sPath", value="存储路径(含文件名的相对路径)", dataType="String", paramType="query", required=true)
	})
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|文件}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=8001, message="未找到文件")
	})
	//[end]
	//@RequestMapping(method=RequestMethod.POST, value="/file/down/zip")
	protected MsgEmity downloadZip(String sPath) {
		return commonService.downloadZip(sPath, fileType());
	}

	/**
	 * 读取文件目录
	 * @param fileTree 读取文件目录
	 * @return MsgEmity 返回查询结果
	 */
	//[start]
	@ApiOperation(value="读取文件目录", notes="读取相对路径下的文件目录", response=FileInfo.class)
	@ApiImplicitParams({
		@ApiImplicitParam(name="sPath", value="存储路径(不含文件名的相对路径)", dataType="String", paramType="query", required=true)
	})
	@ApiResponses({
		@ApiResponse(code=200, message="{\"success\": 布尔值, \"msg\": 文字提示, \"data\": 码值|Json数据对象集合}"),
		@ApiResponse(code=400, message="错误的请求,请检查路径"),
		@ApiResponse(code=404, message="请求路径没有或页面跳转路径不对"),
		@ApiResponse(code=1000001, message="内部请求密钥错误"),
		@ApiResponse(code=1000002, message="您还没有登录或登录已超时,需要重新登录"),
		@ApiResponse(code=1000003, message="检查登录状态失败,请稍后重试！"),
		@ApiResponse(code=1000004, message="请求的操作不存在,请检查访问地址正确性，如大小写"),
		@ApiResponse(code=1000005, message="响应后在系统内部发生不可预知的错误"),
		@ApiResponse(code=1019000, message="1019000~1999999为拦截器调用方法错误"),
		@ApiResponse(code=7001, message="查询数量失败且发生异常"),
		@ApiResponse(code=7002, message="查询数据发生异常，值为null"),
		@ApiResponse(code=7003, message="查询分页数据发生异常"),
		@ApiResponse(code=7004, message="7004~8998为修改时发生的其它错误")
	})
	//[end]
	//@RequestMapping(method={RequestMethod.POST}, value="/file/tree")
	protected MsgEmity fileTree(String sPath) {
		return commonService.fileTree(sPath, fileType());
	}
	
	/**
	 * 获取业务类对象
	 * @return
	 */
	private Object getService() {
		if (null != classService) {
			return classService;
		}
		
		ParameterizedType genericSuperclass = (ParameterizedType)this.getClass().getGenericSuperclass();
		Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();

		Object service = actualTypeArguments[0];
		
		if (null == service || CommonService.class.equals(service)) {
			return null;
		}
		
		classService = service;
		
		return classService;
	}
	
	/**
	 * 获取实体类的类定义
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private Class<?> getEntityClass() {
		if (null != classEntity) {
			return classEntity;
		}
		
		ParameterizedType genericSuperclass = (ParameterizedType)this.getClass().getGenericSuperclass();
		Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();
		classEntity = (Class<E>)actualTypeArguments[1];
		
		return classEntity;
	}
	
	/**
	 * 获取查询条件类的类定义
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private Class<?> getConditionClass() {
		if (null != classCondition) {
			return classCondition;
		}
		
		ParameterizedType genericSuperclass = (ParameterizedType)this.getClass().getGenericSuperclass();
		Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();
		classCondition = (Class<E>)actualTypeArguments[2];
		
		return classCondition;
	}
	
	/**
	 * 判断是否限制仅创建者可操作,5个数的控制分别是:删除、修改、查询、导出、统计
	 * @param i 位数,从左到右从1开始
	 * @return
	 */
	private boolean isOnlyCreator(int i) {
		if (null != this.isInitOnlyCreatorControl) {
			int subValue = ReflectUtil.getAttribute(this, "onlyCreatorControl");//通过反射获得子类属性
			this.onlyCreatorControl = subValue;//覆盖父类属性
			this.isInitOnlyCreatorControl = null;
		}
		
		return '1' == String.valueOf(this.onlyCreatorControl).charAt(i);
	}
	
	/**
	 * 取当前控制层对应的文件分类
	 * @return
	 */
	protected String fileType() {
		String result = this.getClass().getSimpleName();//以控制层的名称作为分类
		
		return result.substring(0, result.lastIndexOf("Control"));//去掉结尾的'Control'既是名称
	}
	
}
